Repository navigation
fix(cli): prevent external state key collisions - #2283
Merged
tamirdresher merged 4 commits intoOct 24, 2026
Merged
tamirdresher merged 4 commits into
tamirdresher merged 4 commits into
Conversation
Contributor
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 4 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | No Copilot review threads |
| ❌ | CI passing | 12 check(s) still running |
Files Changed (4 files, +149 −19)
| File | +/− |
|---|---|
.changeset/1483-external-state-collision.md |
+5 −0 |
docs/src/content/docs/features/external-state.md |
+11 −3 |
packages/squad-cli/src/cli/commands/externalize.ts |
+88 −16 |
test/external-state.test.ts |
+45 −0 |
Total: +149 −19
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
Contributor
🟡 Impact Analysis — PR #2283Risk tier: 🟡 MEDIUM 📊 Summary
🎯 Risk Factors
📦 Modules Affecteddocs (1 file)
root (1 file)
squad-cli (1 file)
tests (1 file)
This report is generated automatically for every PR. See #733 for details. |
omercangumus
marked this pull request as ready for review
October 22, 2026 20:55
omercangumus
requested review from
bradygaster and
tamirdresher
as code owners
October 22, 2026 20:55
Closes github#1483 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
omercangumus
force-pushed
the
omercangumus/1483-external-state-collision
branch
from
October 22, 2026 21:14
bcfe3a3 to
b5bf63d
Compare
tamirdresher
added a commit
that referenced
this pull request
Oct 24, 2026
squad-release-verify.yml ran policy-gates.mjs --mode=release on pull_request too, so every PR carrying a changeset failed the gate (#2283, #2301). The workflow now passes --mode=ci on pull_request and --mode=release only on the release path (workflow_call from squad-release.yml). In ci mode the gate still runs: pending fragments are allowed but must be well-formed (allowlisted package, patch|minor|major bump, non-empty summary); malformed ones fail. Release mode keeps enforcing the drain unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
tamirdresher
added a commit
that referenced
this pull request
Oct 24, 2026
* fix(cli): 2.0.0-preview.2 upgrade/health fixes from dogfooding - upgrade --self: honor --dry-run (zero exec), follow the installed channel (prerelease -> @insider, stable -> @latest), refuse downgrades without --force (#2295) - upgrade: one content-compared plan for every squad-owned file; verified <file>.local-backup before overwrite; shipped-files manifest distinguishes user edits from template revisions; dry-run writes nothing and reports nothing right after an upgrade (also on CRLF checkouts); .gitignore/.gitattributes appended in the file's own EOL; retired files removed when unmodified; provably Squad-shipped stale .copilot/skills copies cleaned (#2297, #2266, #2047, #2232) - health: table headers/placeholders never parsed as agents, built-ins are valid routing targets, BOM/pipe-joined legacy charters parse, missing identity is a warn with a hint, roster drift warns; upgrade adds built-in rows to team.md (#2298, #2234, #1785) - Rai -> rai: two-step rename recorded with git mv; templates reference agents/rai/; init scaffolds rai/ (#2299) - squad client list|add, dry-run header shows project name, update-check stale cache, squad_decide workstream inbox + 80-char slug, doctor Mode: local for same-project teamRoot and no DEP0190 (#2299, #2174) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9 * fix(release): make the changeset-drain policy gate event-aware squad-release-verify.yml ran policy-gates.mjs --mode=release on pull_request too, so every PR carrying a changeset failed the gate (#2283, #2301). The workflow now passes --mode=ci on pull_request and --mode=release only on the release path (workflow_call from squad-release.yml). In ci mode the gate still runs: pending fragments are allowed but must be well-formed (allowlisted package, patch|minor|major bump, non-empty summary); malformed ones fail. Release mode keeps enforcing the drain unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9 * test(cli): align legacy upgrade/help tests with content-compared upgrade and lowercase rai init - upgrade.test: customized-skill expectations now assert the .local-backup message; Rai migration test recreates the legacy mixed-case layout (init scaffolds rai/) - command-help.test: 'client' has a dedicated help block - cli-entry: --self --dry-run returns through the single success branch (performed=false) - team-md: never invent a roster table in a team.md without one - .github/agents/squad.agent.md: agents/rai/ (template-sync parity) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9 * fix(cli): make optional built-ins explicit Keep team.md byte-stable during upgrade, report unconfigured optional built-ins as informational, and add a provenance-backed roster command with exact restore semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9 * fix(upgrade): preserve compound text templates Treat compound .example templates as text for EOL-normalized planning and distinguish unproven first-upgrade provenance from confirmed customization in backup output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9 --------- Co-authored-by: B'Elanna (Squad) <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Prevent
squad externalizefrom moving state into a directory owned by another project.Why
Two different project directories can derive the same project key, causing silent state overwrite. Closes #1483.
How
.owner.jsonmarker before moving files and refuse when the marker names another project.--keyremedy.Validation
Local checks passed:
npm run build,npm run lint,npm run lint:eslint(0 errors),npm test -- test/external-state.test.ts(22 tests), markdownlint, and cspell.The full local
npm testrun did not complete in this environment: it surfaced missingjq, sandbox-denied writes toAppData\\Roaming, and Vitest 4.1.9 where the repo requires Vitest 5.x. A clean-base comparison reproduced all 12AppData\\RoamingEPERMfailures intest/personal-squad-init.test.ts.For the one-commit head
b5bf63d60c630e10bbd93577f36d60fa25552af5, GitHub Actionstestand all applicable checks passed (Squad CI run 39855738598). Its file tree is identical to the previously tested two-commit head.Scope Boundarywas skipped as expected: it only runs forrepo-health/branches or PRs carrying therepo-healthlabel; neither applies here. No merge or auto-merge is enabled.@bradygaster/squad-cliPR Readiness Checklist
Branch & Commit
devcommitfb15fd5devBuild & Test
npm run buildpassesnpm testpasses on GitHub Actions; local full run was blocked by the environment noted abovenpm run lintpassesnpm run lint:eslintpasses (0 errors; existing warnings remain)Changeset
.changeset/1483-external-state-collision.mdDocs
Exports
Breaking Changes
None.
Waivers
None requested.